const SerialPort = MixlyEnv.isClient && require('serialport');
const _ = MixlyEnv.isClient && require('lodash/fp');

var MixlySerial = {};

/**
  * SerialPort对象
  * @type {Object}
  */
MixlySerial.object = null;
MixlySerial.parser = null;
MixlySerial.readLine = null;

/**
  * 储存串口最近一次接收到的数据
  * @type {String}
  */
MixlySerial.receiveData = "";

/**
  * 判断串口工具是否打开，若打开则为true
  * @type {Boolean}
  */
MixlySerial.toolOpened = false;

/**
  * 储存烧录时所用串口的VID与PID值，用来做筛选用
  * @type {Array}
  */
MixlySerial.burnPortType = null;

/**
  * 储存上传时所用串口的VID与PID值，用来做筛选用
  * @type {Array}
  */
MixlySerial.uploadPortType = null;

/**
  * 储存筛选后的串口
  * @type {Array}
  */
MixlySerial.portList = [];

/**
  * 储存上一次上传所使用的串口
  * @type {String}
  */
MixlySerial.selectedPortName = null;

MixlySerial.dtrValue = true;

MixlySerial.rtsValue = false;

function messageDecode(s) {
    if (s) {
        try {
            return decodeURIComponent(s.replace(/_([0-9a-fA-F]{2})/gm, '%$1'));
        } catch (e) {
            return s;
        }
    }
    return s;
}

/**
* @function 设置当前板卡串口的VID和PID
* @description 读取此板卡的配置数据，设置此板卡烧录和上传时的串口PID和VID
* @param type {String} "Burn" - 设置烧录时串口的PID和VID，"Upload" - 设置上传时串口的PID和VID
* @return void
*/
MixlySerial.setPortSelect = function (type) {
    if (typeof MixlyUrl.BOARD_CONFIG[type]?.portSelect == "object"
        && MixlyUrl.BOARD_CONFIG[type].portSelect[0]?.productId
        && MixlyUrl.BOARD_CONFIG[type].portSelect[0]?.vendorId) {
        if (type == "burn")
            MixlySerial.burnPortType = [];
        else
            MixlySerial.uploadPortType = [];
        var i = 0;
        while (MixlyUrl.BOARD_CONFIG[type].portSelect[i]?.productId
            && MixlyUrl.BOARD_CONFIG[type].portSelect[i]?.vendorId) {
            var portSelect = [];
            portSelect.push(MixlyUrl.BOARD_CONFIG[type].portSelect[i].vendorId);
            portSelect.push(MixlyUrl.BOARD_CONFIG[type].portSelect[i].productId);
            if (type == "burn")
                MixlySerial.burnPortType.push(portSelect);
            else
                MixlySerial.uploadPortType.push(portSelect);
            i++;
        }
    } else {
        if (type == "burn")
            MixlySerial.burnPortType = "all";
        else
            MixlySerial.uploadPortType = "all";
    }
}

try {
    MixlySerial.setPortSelect("burn");
    MixlySerial.setPortSelect("upload");
} catch (e) {
    console.log(e);
}

/**
* @function 检测当前环境打开串口工具
* @description 检测当前环境以打开对应的串口工具
* @return void
*/
MixlySerial.init = function () {
    if (MixlyEnv.isClient) {
        MixlySerial.openTool();
    } else {
        MixlyWebSerial.openTool();
    }
}

/**
* @function 打开串口工具
* @description 打开串口工具并打开串口列表中选中的串口
* @return void
*/
MixlySerial.openTool = function () {
    layui.use(['layer', 'element', 'form'], function () {
        var layer = layui.layer;
        var element = layui.element;
        var serial_com_update = null;
        var form = layui.form;

        form.on('checkbox', function (data) {
            if (data.elem.id == "set_dtr" || data.elem.id == "set_rts") {
                MixlySerial.setDtrAndRts();
            } else if (data.elem.id == "send_serial_data_type") {
                if (data.elem.checked) {
                    $("#serial_write").attr("placeholder", indexText["请输入内容"]);
                } else {
                    $("#serial_write").attr("placeholder", indexText["请输入内容"] + "  " + indexText["例如"] + ":0x03 0x04");
                }
            }
        });

        form.on('select(select_com)', function (data) {
            if (MixlySerial.object && MixlySerial.object.isOpen) {
                MixlySerial.object.close();
                setTimeout(function () {
                    MixlySerial.connectPort();
                    MixlyStatusBar.show(1);
                }, 500);
            }
        });

        form.on('select(baud_rates)', function (data) {
            if (MixlySerial.object && MixlySerial.object.isOpen) {
                MixlySerial.object.update({ baudRate: data.value - 0 }, err => { });
            }
        });

        element.on('tab(serial)', function (elem) {
            if (elem.index == 1) {
                MixlyCharts.init();
            } else {
                try {
                    MixlyCharts.chart && MixlyCharts.chart.destroy();
                    MixlyCharts.chart = null;
                } catch (e) {
                    console.log(e);
                }
                MixlyCharts.draw && clearInterval(MixlyCharts.draw);
                MixlyCharts.addData && clearInterval(MixlyCharts.addData);
            }
        });

        layer.open({
            type: 1,
            id: "serial_page",
            title: false,
            area: ["90%", "95%"],
            closeBtn: 1,
            resize: true,
            fixed: true,
            move: $('#serial-move'),
            content: $('#serial-form'),
            success: function (layero, index) {
                try {
                    var now_page = document.getElementById(layero.selector.replace("#", ""));
                    now_page.style.minWidth = "600px";
                    now_page.style.minHeight = "300px";
                    now_page.style.maxWidth = "710px";
                    now_page.style.maxHeight = "600px";
                    var now_height = document.documentElement.clientHeight;
                    var now_width = document.documentElement.clientWidth;
                    now_page.style.left = (now_width - now_page.clientWidth) / 2 + "px";
                    now_page.style.top = (now_height - now_page.clientHeight) / 2 + "px";
                    now_page.style.borderRadius = "8px";
                } catch (e) {
                    console.log(e);
                }

                var serialPage = document.getElementById("serial_page");
                serialPage.style.overflow = "hidden";
                serialPage.style.maxWidth = "710px";
                serialPage.style.maxHeight = "600px";
                serialPage.style.minWidth = "600px";
                serialPage.style.minHeight = "300px";
                serialPage.style.borderRadius = "8px";

                layero[0].childNodes[1].childNodes[0].classList.remove('layui-layer-close2');
                layero[0].childNodes[1].childNodes[0].classList.add('layui-layer-close1');

                serial_com_update = setInterval(MixlySerial.refreshPortSelectBox, 1200);
                MixlySerial.refreshPortList(MixlySerial.uploadPortType, function () {
                    MixlySerial.updateSelectBox(MixlySerial.portList);
                    if (MixlySerial.object && MixlySerial.object.isOpen) {
                        if (MixlyStatusBar.portAce[MixlySerial.object.path]) {
                            $("#serial_content").val("");
                            //在某些情况下读取状态栏数据到串口监视器可能会让串口监视器卡顿，因此暂时注释掉
                            //$("#serial_content").val(MixlyStatusBarPort.getValue(MixlySerial.object.path));
                        }
                    } else {
                        $("#serial_content").val("");
                    }
                    MixlySerial.connectPort();
                    MixlyStatusBar.show(1);
                    MixlySerial.toolOpened = true;
                });
                $(".layui-layer-page").css("z-index","198910151");

            },
            end: function () {
                $(".layui-layer-shade").css("display","none");
                document.getElementById('serial-form').style.display = 'none';
                if (MixlySerial.object && MixlySerial.object.isOpen && $("#serial_content").val() != "") {
                    if (MixlyStatusBar.portAce[MixlySerial.object.path]) {
                        MixlyStatusBarPort.setValue(MixlySerial.object.path, $("#serial_content").val(), true);
                    }
                }
                try {
                    MixlyCharts.chart && MixlyCharts.chart.destroy();
                    MixlyCharts.chart = null;
                } catch (e) {
                    console.log(e);
                }
                MixlyCharts.draw && clearInterval(MixlyCharts.draw);
                MixlyCharts.addData && clearInterval(MixlyCharts.addData);
                serial_com_update && clearInterval(serial_com_update);
                element.tabChange('serial', '1');
                MixlySerial.toolOpened = false;
            },
            resizing: function (layero) {
                var nowHeight = document.documentElement.clientHeight;
                var nowWidth = document.documentElement.clientWidth;
                layero[0].style.width = layero[0].clientWidth/nowWidth*100 + "%";
                layero[0].style.height = layero[0].clientHeight/nowHeight*100 + "%";
            }
        });
    });
}

/**
* @function 初始化串口列表
* @description 通过传入的串口PID和VID初始化串口列表
* @param select {Array | String} 通过串口的VID和PID获取对应串口，当为all时，则获取全部串口
* @param cb {function} 
* @return void
*/
MixlySerial.initPortList = function (select, cb) {
    SerialPort.list().then(ports => {
        const names = ports.map(p => {
            if (MixlyEnv.currentPlatform == "linux" && p.comName.indexOf('ttyS') != -1) {
                return "";
            }
            if (select == "all")
                return p.comName;
            if (typeof (select) == "object") {
                if (typeof (select[0]) == "object") {
                    for (var i = 0; i < select.length; i++) {
                        for (var j = 0; j < select[i].length; j++) {
                            if (select[i].length == 2
                                && p.vendorId
                                && p.productId
                                && p.vendorId.toLowerCase() == select[i][0].toLowerCase()
                                && p.productId.toLowerCase() == select[i][1].toLowerCase()) {
                                return p.comName;
                            }
                        }
                    }
                } else {
                    if (select.length == 2
                        && p.vendorId
                        && p.productId
                        && p.vendorId.toLowerCase() == select[0].toLowerCase()
                        && p.productId.toLowerCase() == select[1].toLowerCase()) {
                        return p.comName;
                    }
                }
            }
        });
        if (typeof cb === 'function') {
            cb(names);
        }
    });
}

/**
* @function 刷新串口列表
* @description 刷新串口列表，更新数据到MixlySerial.portList
* @param portSelect {Array | String} 通过串口的VID和PID获取对应串口，当为all时，则获取全部串口
* @param doFunc {function} 串口刷新结束后所要执行的操作
* @return void
*/
MixlySerial.refreshPortList = function (portSelect, doFunc) {
    MixlySerial.portList = [];
    var newPortList = [];
    MixlySerial.initPortList(portSelect, ports => {
        _.map(v => {
            if (v != undefined) {
                MixlySerial.portList.push(v);
            }
        }, ports);
        doFunc();
    });
}

/**
* @function 获取最新的串口列表
* @description 获取最新的串口列表
* @param portSelect {Array | String} 通过串口的VID和PID获取对应串口，当为all时，则获取全部串口
* @param doFunc {function} 串口刷新结束后所要执行的操作
* @return void
*/
MixlySerial.getPortList = function (portSelect, doFunc) {
    var newPortList = [];
    MixlySerial.initPortList(portSelect, ports => {
        _.map(v => {
            if (v != undefined) {
                newPortList.push(v);
            }
        }, ports);
        doFunc(newPortList);
    });
}

/**
* @function 更新串口列表到串口选择框
* @description 通过传入串口列表以更新串口选择框
* @param portArr {Array} 串口列表
* @return void
*/
MixlySerial.updateSelectBox = function (portArr) {
    var form = layui.form;
    const devNames = $('#select_com');
    devNames.empty();
    _.map(v => {
        if (MixlySerial.selectedPortName == v) {
            devNames.append($(`<option value="${v}" selected>${v}</option>`));
        } else {
            devNames.append($(`<option value="${v}">${v}</option>`));
        }
    }, portArr);
    form.render();
}

/**
* @function 连接串口
* @description 读取串口下拉列表中选中的串口并连接
* @param port {String} 串口号
* @param baud {Number} 波特率
* @return void
*/
MixlySerial.connectPort = function (port = null, baud = null) {
    if (port == null)
        port = $('#select_com option:selected').val();
    if (baud == null)
        baud = $('#div_cb_cf_baud_rates option:selected').val() - 0;
    if (!port)
        return;
    if (MixlySerial.object && (MixlySerial.object.isOpen || MixlySerial.object.opening)) {
        if (MixlySerial.object.path == port) {
            return;
        } else {
            MixlySerial.object.close();
            return;
        }
    }
    MixlySerial.object = new SerialPort(port, {
        baudRate: baud - 0,  //波特率
        dataBits: 8,    //数据位
        parity: 'none',  //奇偶校验
        stopBits: 1,  //停止位
        flowControl: false,
        autoOpen: false //不自动打开1
    }, false);
    MixlySerial.selectedPortName = port;
    MixlySerial.readLine = SerialPort.parsers.Readline;
    MixlySerial.ByteLength = SerialPort.parsers.ByteLength;
    MixlySerial.receiveBuff = [];
    MixlySerial.chineseStr = "";
    MixlySerial.buffLength = 0;
    MixlySerial.parser = new MixlySerial.readLine();
    MixlySerial.parserBytes = MixlySerial.object.pipe(new MixlySerial.ByteLength({ length: 1 }))
    MixlySerial.object.pipe(MixlySerial.parser);
    var serialDataUpdate = null;
    MixlySerial.object.open(function (error) {
        if (error) {
            console.log('failed to open: ' + error);
            MixlyStatusBarPort.setValue(port, error + '\n', true);
            $("#serial_content").val($("#serial_content").val() + error + '\n');
            $("#serial_content").scrollTop($("#serial_content")[0].scrollHeight);
            MixlySerial.object = null;
            $("#button_connect").text(indexText["打开"]);
            $("#button_connect").attr("class", "layui-btn layui-btn-normal");
            return;
        } else {
            MixlyStatusBar.tabAdd(port);
            MixlyStatusBar.taChange(port);

            $("#button_connect").text(indexText["关闭"]);
            $("#button_connect").attr("class", "layui-btn layui-btn-danger");
            MixlyStatusBarPort.setValue(port, indexText['已打开串口'] + ': ' + port + '\n', true);

            $("#serial_content").val(indexText['已打开串口'] + ': ' + port + '\n');
            $("#serial_content").scrollTop($("#serial_content")[0].scrollHeight);

            serialDataUpdate = setInterval(MixlySerial.refreshOutputBox, 100);
        }
    });

    MixlySerial.parserBytes.on('data', function (data) {
        /*  UTF-8编码方式
        *   ------------------------------------------------------------
        *   |1字节 0xxxxxxx                                             |
        *   |2字节 110xxxxx 10xxxxxx                                    |
        *   |3字节 1110xxxx 10xxxxxx 10xxxxxx                           |
        *   |4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx                  |
        *   |5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx         |
        *   |6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx|
        *   ------------------------------------------------------------
        */
        if ((data[0] & 0x80) == 0x00) {
            if (MixlySerial.chineseStr !== "") {
                try {
                    let dataArr = String.fromCharCode(data[0]).match(/\w/g);
                    if (dataArr && dataArr.length > 0) {
                        MixlySerial.chineseStr += data;
                    } else {
                        MixlySerial.receiveData += messageDecode(MixlySerial.chineseStr);
                        MixlySerial.receiveData += data;
                        MixlySerial.chineseStr = "";
                    }
                } catch(e) {
                    console.log(e);
                    MixlySerial.receiveData += messageDecode(MixlySerial.chineseStr);
                    MixlySerial.receiveData += data;
                    MixlySerial.chineseStr = "";
                }
            } else {
                if (data[0] !== 95) {
                    MixlySerial.receiveData += data;
                } else {
                    MixlySerial.chineseStr = String.fromCharCode(data[0]);
                }
            }
        } else if ((data[0] & 0xc0) == 0x80) {
            MixlySerial.receiveBuff.push(data[0]);
            if (MixlySerial.receiveBuff.length >= MixlySerial.buffLength) {
                MixlySerial.receiveData += Buffer.from(MixlySerial.receiveBuff);
                MixlySerial.receiveBuff = [];
            }
        } else {
            let dataNum = data[0] & 0xe0;
            switch (dataNum) {
                case 0xfc:
                    MixlySerial.buffLength = 6;
                    break;
                case 0xf8:
                    MixlySerial.buffLength = 5;
                    break;
                case 0xf0:
                    MixlySerial.buffLength = 4;
                    break;
                case 0xe0:
                    MixlySerial.buffLength = 3;
                    break;
                case 0xc0:
                default:
                    MixlySerial.buffLength = 2;
            }
            MixlySerial.receiveBuff.push(data[0]);
        }
    });

    MixlySerial.parser.on('data', function (data) {
        MixlyCharts.addData(data);
    });

    MixlySerial.object.on('error', function (err) {
        serialDataUpdate && clearInterval(serialDataUpdate);
        MixlyStatusBar.taChange("output");
        MixlySerial.showErrorData(port, MixlySerial.toolOpened, err);
    });

    MixlySerial.object.on('open', () => {
        MixlySerial.setDtrAndRts();
    })

    //串口结束使用时执行此函数
    MixlySerial.object.on('close', () => {
        //MixlyStatusBar.taChange("output");
        MixlyStatusBarPort.close(port);
        $("#button_connect").text(indexText["打开"]);
        $("#button_connect").attr("class", "layui-btn layui-btn-normal");
        serialDataUpdate && clearInterval(serialDataUpdate);
        if ($("#serial_content").val().lastIndexOf("\n") != $("#serial_content").val().length - 1) {
            $("#serial_content").val($("#serial_content").val() + '\n' + indexText['已关闭串口'] + ': ' + port + '\n');
        } else {
            $("#serial_content").val($("#serial_content").val() + indexText['已关闭串口'] + ': ' + port + '\n');
        }
        $("#serial_content").scrollTop($("#serial_content")[0].scrollHeight);

        if (MixlyStatusBarPort.getValue(port).lastIndexOf("\n") != MixlyStatusBarPort.getValue(port).length - 1) {
            MixlyStatusBarPort.addValue(port, '\n' + indexText['已关闭串口'] + ': ' + port + '\n', true);
        } else {
            MixlyStatusBarPort.addValue(port, indexText['已关闭串口'] + ': ' + port + '\n', true);
        }
        MixlySerial.object = null;
    });
}

/**
* @function 打开或关闭串口
* @description 若串口已打开，则关闭它，反之则打开它
* @return void
*/
MixlySerial.portOpenOrClose = function () {
    if (MixlySerial.object && (MixlySerial.object.isOpen || MixlySerial.object.opening)) {
        MixlySerial.object.close();
    } else {
        MixlySerial.connectPort();
        MixlyStatusBar.show(1);
    }
}

/**
* @function 显示串口报错信息到串口输出框或状态栏
* @description 
* @param select {Boolean} true - 显示报错信息到串口输出框，false - 显示报错信息到状态栏
* @param data {String} 报错信息
* @return void
*/
MixlySerial.showErrorData = function (port, select, data) {
    if ($("#receive_serial_data_type")[0].checked == false) {
        data = Uint8ArrayToString(stringToByte(data));
        data = data.replace(/^\s*/, "");
        data += "\n";
    }
    if (select) {
        $("#serial_content").val($("#serial_content").val() + data);
        $("#screen_scroll")[0].checked == true && $("#serial_content").scrollTop($("#serial_content")[0].scrollHeight);
    } else {
        MixlyStatusBarPort.addValue(port, data, true);
    }
}

function stringToByte(str) {
    var len, c;
    len = str.length;
    var bytes = [];
    for (var i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if (c >= 0x010000 && c <= 0x10FFFF) {
            bytes.push(((c >> 18) & 0x07) | 0xF0);
            bytes.push(((c >> 12) & 0x3F) | 0x80);
            bytes.push(((c >> 6) & 0x3F) | 0x80);
            bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000800 && c <= 0x00FFFF) {
            bytes.push(((c >> 12) & 0x0F) | 0xE0);
            bytes.push(((c >> 6) & 0x3F) | 0x80);
            bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000080 && c <= 0x0007FF) {
            bytes.push(((c >> 6) & 0x1F) | 0xC0);
            bytes.push((c & 0x3F) | 0x80);
        } else {
            bytes.push(c & 0xFF);
        }
    }
    return new Int8Array(bytes);
}

function Uint8ArrayToString(fileData) {
    var dataString = "";
    for (var i = 0; i < fileData.length; i++) {
        var convert = (fileData[i]).toString(16);
        if (convert.length % 2 == 1)
            convert = "0" + convert;
        dataString = dataString + " " + convert.toUpperCase();
    }

    return dataString;

}

/**
* @function 串口发送字节数组
* @description 
* @param sendDataStr {String} 要发送的数据
* @param sendDataTail {String} 数据的尾部
* @return void
*/
MixlySerial.writeByteArr = function (sendDataStr, sendDataTail) {
    var sendDataArr = sendDataStr.trim().split(/\s+/);
    var sendDataNum = [];
    for (var i = 0; i < sendDataArr.length; i++) {
        if (parseInt(sendDataArr[i], 16)) {
            sendDataNum.push(parseInt(sendDataArr[i], 16));
        }
    }
    MixlySerial.object.write(sendDataNum);
    sendDataTail = sendDataTail.replace("\\r", "\r");
    sendDataTail = sendDataTail.replace("\\n", "\n");
    if (sendDataTail == "no") {
        sendDataTail = "";
    }
    if (sendDataTail) {
        MixlySerial.object.write(sendDataTail);
        $("#serial_write").val("");
    }
}

/**
* @function 串口发送字符串
* @description 串口发送字符串
* @return void
*/
MixlySerial.writeString = function () {
    if (MixlySerial.object) {
        var sendDataStr = $("#serial_write_string").val();
        var sendDataTail = $('#send_string_data_with option:selected').val();
        sendDataTail = sendDataTail.replace("\\r", "\r");
        sendDataTail = sendDataTail.replace("\\n", "\n");
        if (sendDataTail == "no") {
            sendDataTail = "";
        }
        if (sendDataStr) {
            MixlySerial.object.write(sendDataStr + sendDataTail);
            $("#serial_write_string").val("");
        }
    }
}

/**
* @function 读取串口发送框数据并发送
* @description 读取串口发送框数据并发送，然后清空串口发送框
* @return void
*/
MixlySerial.write = function () {
    if (MixlySerial.object) {
        var sendDataStr = $("#serial_write").val();
        var sendDataTail = $('#send_data_with option:selected').val();
        if ($("#send_serial_data_type")[0].checked == false) {
            MixlySerial.writeByteArr(sendDataStr, sendDataTail);
        } else {
            sendDataTail = sendDataTail.replace("\\r", "\r");
            sendDataTail = sendDataTail.replace("\\n", "\n");
            if (sendDataTail == "no") {
                sendDataTail = "";
            }
            if (sendDataStr) {
                MixlySerial.object.write(sendDataStr + sendDataTail);
                $("#serial_write").val("");
            }
        }
    }
}

/**
* @function 串口发送
* @description 串口发送Ctrl + C
* @return void
*/
MixlySerial.writeCtrlC = function () {
    if (MixlySerial.object) {
        MixlySerial.object.write([3, 13, 10]);
    }
}

/**
* @function 串口发送
* @description 串口发送Ctrl + D
* @return void
*/
MixlySerial.writeCtrlD = function () {
    if (MixlySerial.object) {
        MixlySerial.object.write([3, 4]);
    }
}

/**
* @function 清空串口输出框
* @description 清空当前串口输出框中的数据
* @return void
*/
MixlySerial.clearContent = function () {
    document.getElementById('serial_content').value = '';
}

/**
* @function 刷新串口选择框
* @description 获取最新的串口列表并刷新串口选择框
* @return void
*/
MixlySerial.refreshPortSelectBox = function () {
    MixlySerial.getPortList(MixlySerial.uploadPortType, function (newPortList) {
        if (newPortList.toString() != MixlySerial.portList.toString()) {
            MixlySerial.updateSelectBox(newPortList);
            MixlySerial.portList = newPortList;
        }
    })
}

/**
* @function 更新串口输出框中数据
* @description 更新串口数据到串口输出框
* @return void
*/
MixlySerial.refreshOutputBox = function () {
    if (!MixlySerial.object) {
        return;
    }
    if (!MixlySerial.object.isOpen) {
        return;
    }
    var oldReceiveData = "";
    var disposeData = [];
    if (MixlySerial.toolOpened) {
        oldReceiveData = $("#serial_content").val();
    } else {
        oldReceiveData = MixlyStatusBarPort.getValue(MixlySerial.object.path);
    }

    disposeData = oldReceiveData.split(/\r\n/);

    if ($("#receive_serial_data_type")[0].checked == false) {
        MixlySerial.receiveData = Uint8ArrayToString(stringToByte(MixlySerial.receiveData));
        MixlySerial.receiveData = MixlySerial.receiveData.replace(/^\s*/, "");
    }

    oldReceiveData = "";
    if (disposeData.length >= 1000) {
        for (var z = disposeData.length - 1000; z < disposeData.length - 1; z++) {
            oldReceiveData += disposeData[z] + "\n";
        }
    } else {
        for (var z = 0; z < disposeData.length - 1; z++) {
            oldReceiveData += disposeData[z] + "\n";
        }
    }
    oldReceiveData += disposeData[disposeData.length - 1];
    if (MixlySerial.toolOpened) {
        $("#serial_content").val(oldReceiveData + MixlySerial.receiveData);
        $("#screen_scroll")[0].checked == true && $("#serial_content").scrollTop($("#serial_content")[0].scrollHeight);
    } else {
        if (oldReceiveData + MixlySerial.receiveData == "\n") {
            MixlyStatusBarPort.setValue(MixlySerial.object.path, '', true);
        } else {
            MixlyStatusBarPort.setValue(MixlySerial.object.path, oldReceiveData + MixlySerial.receiveData, true);
        }
    }
    MixlySerial.receiveData = "";
}

MixlySerial.setDtrAndRts = function () {
    if (MixlySerial.object && MixlySerial.object.isOpen) {
        MixlySerial.object.set({ dtr: $("#set_dtr")[0].checked ?? true, rts: $("#set_rts")[0].checked ?? true });
    }
}
